<?php

require_once 'Kanedo/NestedSets.php';
require_once 'Kanedo/Db/Exception.php';

class NavigationTree extends Kanedo_NestedSets 
{
	protected $_site = null;
	protected $_pkSite = "site_id_site";
	
	public function setSiteObject(Site $obj)
	{
		$this->_site = $obj;
	}
	public function setSiteRelation(string $pk)
	{
		$this->_pkSite = $pk;
	}
	/**
	 * Funktion um Wurzelknoten zu erstellen. Im Normalfall nicht so oft verwendet
	 *
	 * @param string $name
	 */
	public function createRootNode($name)
	{
		$sql = "INSERT INTO `".$this->_table."` (".$this->_name.", lft, rgt) VALUES ('".$name."', 1,2);";
		$this->_db->executeQuery($sql);
	}
	public function getTree()
	{
		$sql = "SELECT n.".$this->_primaryKey.", n.".$this->_name.", n.".$this->_pkSite.", COUNT(*)-1 AS level FROM ".$this->_table." AS n, ".$this->_table." AS p WHERE n.lft BETWEEN p.lft AND p.rgt GROUP BY n.lft ORDER BY n.lft;";
		$return = $this->_db->executeQuery($sql);
		if(!$return)
		{
			throw new Kanedo_Db_Exception('no_data_in_db');
		}
		$data =  $this->_db->fetchAll($return);
		 $struct = array(); // Fertiges Array
		$level = 0; 
		$helper =& $struct;
		foreach($data as $item) 
		{
		    if($level < $item['level']) 
		    {
		        $keys = array_keys($helper);
		        $helper =& $helper[$keys[count($keys)-1]]['children'];
		        
		        
		    }else if($level > $item['level']) 
		    {
		        $helper =& $struct;
		        
		        for($i=0; $i<$level-1; $i++) 
		        {
		            $keys = array_keys($helper);
		            $helper =& $helper[$keys[count($keys)-1]]['children'];
		            
		        }
		    }
		    $helper[] = array( 
		        'id'       => $item[$this->_primaryKey],
		        'name'     => $item[$this->_name],
		    	'siteId'   => $item[$this->_pkSite],
		        'children' => array()
		    );
		    $level = $item['level'];
		}
		return $struct;
		
	}
	public function getHTMLTree()
	{
		$data = $this->getTree();
		return $this->recursiveTree($data, true);
	}
	
	protected function recursiveTree($node, $root = false)
	{
		$data = $node;
		$return = "";
		for ($i = 0; $i<count($data); $i++)
		{
			if($root) {
				$return .= "<ul class=\"root-node\">\n";
				$return .= "\t<li class=\"root-node\">";
			}else {
				$return .= "<ul class=\"node\">\n";
				$return .= "\t<li class=\"node\">";
			}
			$return .= '<a href="/admin/site/add?parent='.$data[$i]["siteId"].'" title="Neue Seite Hinzuf&uuml;gen"><img src="/IMAGES/dom_tree_new.png" alt="Neu" /></a>';
			$return .= "<a href='/admin/site/edit?id=".$data[$i]["siteId"]."' title='Seite Bearbeiten'>".$data[$i]["name"]."</a>";
			if (is_array($data[$i]['children']))
			{
				$return .= $this->recursiveTree($data[$i]['children']);
			}
			$return .= "</li>\n";
			$return .= "</ul>\n";			
		}
		return $return;
	}
	
	public function insertChildNode($name, $siteId, $parent)
	{
		$parentNode = $this->getNodeByColumn('site_id_site', $parent);
		if ($parentNode['lft'] == 1)
		{
			$this->insertFirstChild($name, $siteId);
		}else {
			$this->insertNode($name, $parentNode['lft'],$parentNode['rgt'], $siteId);	
		}	
	}
	
	/**
	 * Kinderknoten einfuegen
	 *
	 * @param string $name
	 * @param int $lft
	 * @param int $rgt
	 * @param int $siteId
	 */
	public function insertNode($name, $lft, $rgt, $siteId)
	{
		$sql = "UPDATE ".$this->_table." SET rgt = rgt +2 WHERE rgt >= ".$rgt.";";
		$this->_db->executeQuery($sql);
		$sql = "UPDATE ".$this->_table." SET lft = lft +2 WHERE lft > ".$rgt.";";
		$this->_db->executeQuery($sql);
		$sql = "INSERT INTO ".$this->_table." (".$this->_name.", lft,rgt, ".$this->_pkSite.") VALUES('".$name."', ".$rgt.", ".$rgt."+1, ".$siteId.");";
		$this->_db->executeQuery($sql);
	}
	
	public function insertFirstChild($name, $siteId)
	{
		$root = $this->getRootNode();
		$sql = "UPDATE ".$this->_table." SET rgt = rgt + 2 WHERE rgt = ".$root['rgt'].";";
		$this->_db->executeQuery($sql);
		$sql = "INSERT INTO ".$this->_table." (".$this->_name.",lft,rgt, ".$this->_pkSite.") VALUES ('".$name."', ".$root['rgt'].",".$root['rgt']."+1, ".$siteId.");";
		$this->_db->executeQuery($sql);
	}
	public function getNodeByColumn($col, $val)
	{
		$col = $this->_db->escape($col);
		$var = $this->_db->escape($val);
		$sql = "SELECT * FROM ".$this->_table." WHERE ".$col." = '".$var."'";
		$row = $this->_db->fetchAll($this->_db->executeQuery($sql));
		if($row[0]){
			return $row[0];
		}else {
			require_once 'Kanedo/NestedSets/Exception.php';
			throw new Kanedo_NestedSets_Exception('no_node');
		} 
	}
	
	public function updateNodeById($id, array $cols)
	{
		$update = "";
		$i = 1;
		foreach($cols as $key => $val)
		{
			if($i == count($cols))
			$update .= "`".$key."` = '".$val."'";
			else $update .= "`".$key."` = '".$val."',";	
			
			$i++;
		}
		$sql = "UPDATE `".$this->_table."` SET ".$update." WHERE `site_id_site` =".(int)$id.";";
		$result = $this->_db->executeQuery($sql);
		if (!$result)
		{
			throw new Kanedo_Db_Exception('invalid_ressource');
		}
	}
	
	public function getNodeByPath($path, $seperator = "/")
	{
		$sql = "SELECT 
	`nodes`.*, 
	COUNT(*) - 1 AS `level`, 
	(
		SELECT 
			GROUP_CONCAT(`sub_parent`.`name` SEPARATOR '/')
		FROM 
			`categories` AS `sub_nodes`, 
			`categories` AS `sub_parent`
		WHERE 
			`sub_nodes`.`lft` BETWEEN `sub_parent`.`lft` AND `sub_parent`.`rgt` AND `sub_nodes`.`id` = `nodes`.`id`
		GROUP BY
			`sub_parent`.`site`
		ORDER BY 
			`sub_parent`.`lft`
	) AS path
		FROM 
			`categories` AS `nodes`, 
			`categories` AS `parent` 
		WHERE 
			`nodes`.`lft` BETWEEN `parent`.`lft` AND `parent`.`rgt` 
		GROUP BY 
			`nodes`.`lft` 
		HAVING 
			`path` = 'folder-1/folder-2/folder-5'
		ORDER BY 
			`nodes`.`lft`";
	}
}
?>